package pub.guoxin.oops.analysis.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.DecoderException;
import org.assertj.core.util.Lists;
import org.springframework.stereotype.Service;
import pub.guoxin.oops.analysis.service.AbstractDataAnalysisService;
import pub.guoxin.oops.constants.CDI;
import pub.guoxin.oops.constants.DDI;
import pub.guoxin.oops.model.Communication;
import pub.guoxin.oops.model.DeviceDataInfo;
import pub.guoxin.oops.utils.BytesUtils;
import pub.guoxin.oops.utils.HexConvertUtils;
import pub.guoxin.oops.utils.LocalDateUtils;

import java.nio.charset.CharacterCodingException;
import java.time.LocalDateTime;
import java.util.List;

/**
 * Created by guoxin on 17-10-18.
 */
@Slf4j
@Service
public class DataAnalysisServiceImpl extends AbstractDataAnalysisService {

    public static void main(String[] args) {
        int i = 109;
        int i1 = i % DDI.TOTAL_LENGTH;
        System.out.println(i1);
        boolean b = i1 == CDI.TOTAL_LENGTH;
        System.out.println(b);
    }

    @Override
    public Communication analysisCommunicationData(String hexString) throws DecoderException {

        if (hexString.length() / 2 % DDI.TOTAL_LENGTH != CDI.TOTAL_LENGTH) // 验证数据格式是否错误
            return null;

        Communication communication = new Communication();
        {
            /* 协议ID */
            String stringBuffer = BytesUtils.subStringByIndex(hexString, CDI.BEGINNING_INDEX, CDI.PID);
            log.info("协议ID: {}", stringBuffer);
        }
        {
            /* id */
            String stringBuffer = BytesUtils.subStringByIndex(hexString, CDI.PID, CDI.ID);
            int id = HexConvertUtils.hexString2Int(stringBuffer);
            communication.setSn(Integer.toString(id));
        }
        {
            /* batteryLevel(电池电量) */
            String stringBuffer = BytesUtils.subStringByIndex(hexString, CDI.ID, CDI.BATTERY_LEVEL);
            float batteryLevel = HexConvertUtils.hexString2Float(stringBuffer);
            communication.setBatteryLevel(batteryLevel);
        }
        {
            /* version(版本号) */
            String stringBuffer = BytesUtils.subStringByIndex(hexString, CDI.BATTERY_LEVEL, CDI.VERSION);
            int version = HexConvertUtils.hexString2Int(stringBuffer);
            communication.setVersion(version);
        }
        {
            /* longitude(经度) */
            String stringBuffer = BytesUtils.subStringByIndex(hexString, CDI.VERSION, CDI.LONGITUDE);
            float longitude = HexConvertUtils.hexString2Float(stringBuffer);
            log.info("~~~~~~~~~~~~~~longitude{}", longitude);
            communication.setLongitude(longitude);
        }
        {
            /* latitude(纬度) */
            String stringBuffer = BytesUtils.subStringByIndex(hexString, CDI.LONGITUDE, CDI.LATITUDE);
            float latitude = HexConvertUtils.hexString2Float(stringBuffer);
            log.info("~~~~~~~~~~~~~~latitude{}", latitude);
            communication.setLatitude(latitude);
        }
        {
            /* dateTime(时间戳) */
            String stringBuffer = BytesUtils.subStringByIndex(hexString, CDI.LATITUDE, CDI.DATETIME);
            log.info("~~~~~~~~~~~~~~~~~~~~~~~{}", stringBuffer);
            String dateTime = HexConvertUtils.hexString2String(stringBuffer);
            log.info("~~~~~~~~~~~~~~~~~~~~~~~{}", dateTime);
            communication.setDateTime(LocalDateUtils.format(dateTime, LocalDateUtils.yyMMddHHmmss));
        }
        return communication;
    }

    @Override
    public List<DeviceDataInfo> analysisDeviceInfoData(String hexString) throws IllegalArgumentException, DecoderException, CharacterCodingException {
        LocalDateTime time = null;
        {
            String stringBuffer = BytesUtils.subStringByIndex(hexString, CDI.LATITUDE, CDI.DATETIME);
            String dateTime = HexConvertUtils.hexString2String(stringBuffer);
            time = LocalDateUtils.format(dateTime, LocalDateUtils.yyMMddHHmmss);
        }

        int cycleIndex = (hexString.length() / 2 - CDI.TOTAL_LENGTH) / DDI.TOTAL_LENGTH; // 循环变量
        List<DeviceDataInfo> devices = Lists.newArrayList();
        for (int i = 0; i < cycleIndex; i++) {
            DeviceDataInfo device = new DeviceDataInfo();
            {
                device.setDateTime(time);
            }
            {
                /* id(设备号) */
                String stringBuffer = BytesUtils.subStringByIndex(hexString, calculations(i, DDI.BEGINNING_INDEX), calculations(i, DDI.ID));
                log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{}: ", stringBuffer);
                String sn = HexConvertUtils.hexString2String(stringBuffer);
                device.setSn(sn.trim());
            }
            {
                /* compressibilityRatio(压缩系数比) */
                String stringBuffer = BytesUtils.subStringByIndex(hexString, calculations(i, DDI.ID), calculations(i, DDI.COMPRESSIBILITY_RATIO));
                float compressibilityRatio = HexConvertUtils.hexString2Float(stringBuffer);
                device.setCompressibilityRatio(compressibilityRatio);
            }
            {
                /* correctionCoefficient(修正系数比) */
                String stringBuffer = BytesUtils.subStringByIndex(hexString, calculations(i, DDI.COMPRESSIBILITY_RATIO), calculations(i, DDI.CORRECTION_COEFFICIENT));
                float correctionCoefficient = HexConvertUtils.hexString2Float(stringBuffer);
                device.setCorrectionCoefficient(correctionCoefficient);
            }
            {
                /* kCoefficient(K系数) */
                String stringBuffer = BytesUtils.subStringByIndex(hexString, calculations(i, DDI.CORRECTION_COEFFICIENT), calculations(i, DDI.K_COEFFICIENT));
                float kCoefficient = HexConvertUtils.hexString2Float(stringBuffer);
                device.setKCoefficient(kCoefficient);
            }
            {
                /* meterKCoefficient(仪表K系数) */
                String stringBuffer = BytesUtils.subStringByIndex(hexString, calculations(i, DDI.K_COEFFICIENT), calculations(i, DDI.METER_K_COEFFICIENT));
                float meterKCoefficient = HexConvertUtils.hexString2Float(stringBuffer);
                device.setMeterKCoefficient(meterKCoefficient);
            }
            {
                /* errorTemperature(温度测量错误时代替值) */
                String stringBuffer = BytesUtils.subStringByIndex(hexString, calculations(i, DDI.METER_K_COEFFICIENT), calculations(i, DDI.ERROR_TEMPERATURE));
                float errorTemperature = HexConvertUtils.hexString2Float(stringBuffer);
                device.setErrorTemperature(errorTemperature);
            }
            {
                /* errorTemperature(气压测量错误时代替值) */
                String stringBuffer = BytesUtils.subStringByIndex(hexString, calculations(i, DDI.ERROR_TEMPERATURE), calculations(i, DDI.ERROR_AIR_PRESSURE));
                float errorAirPressure = HexConvertUtils.hexString2Float(stringBuffer);
                device.setErrorAirPressure(errorAirPressure);
            }
            {
                /* normCumulant(标况累积量) */
                String stringBuffer = BytesUtils.subStringByIndex(hexString, calculations(i, DDI.ERROR_AIR_PRESSURE), calculations(i, DDI.NORM_CUMULANT));
                double normCumulant = HexConvertUtils.hexString2Double(stringBuffer);
                device.setNormCumulant(normCumulant);
            }
            {
                /* workCumulant(工况累积量) */
                String stringBuffer = BytesUtils.subStringByIndex(hexString, calculations(i, DDI.NORM_CUMULANT), calculations(i, DDI.WORK_CUMULANT));
                long workCumulant = HexConvertUtils.hexString2Long(stringBuffer);
                device.setWorkCumulant(workCumulant);
            }
            {
                /* errorNormCumulant(错误标况累积量) */
                String stringBuffer = BytesUtils.subStringByIndex(hexString, calculations(i, DDI.WORK_CUMULANT), calculations(i, DDI.ERROR_NORM_CUMULANT));
                double errorNormCumulant = HexConvertUtils.hexString2Double(stringBuffer);
                device.setErrorNormCumulant(errorNormCumulant);
            }
            {
                /* errorWorkCumulant(错误工况累积量) */
                String stringBuffer = BytesUtils.subStringByIndex(hexString, calculations(i, DDI.ERROR_NORM_CUMULANT), calculations(i, DDI.ERROR_WORK_CUMULANT));
                long errorWorkCumulant = HexConvertUtils.hexString2Long(stringBuffer);
                device.setErrorWorkCumulant(errorWorkCumulant);
            }
            {
                /* workPressure(工况压力) */
                String stringBuffer = BytesUtils.subStringByIndex(hexString, calculations(i, DDI.ERROR_WORK_CUMULANT), calculations(i, DDI.WORK_PRESSURE));
                float workPressure = HexConvertUtils.hexString2Float(stringBuffer);
                device.setWorkPressure(workPressure);
            }
            {
                /* workTemperature(工况温蒂) */
                String stringBuffer = BytesUtils.subStringByIndex(hexString, calculations(i, DDI.WORK_PRESSURE), calculations(i, DDI.WORK_TEMPERATURE));
                float workTemperature = HexConvertUtils.hexString2Float(stringBuffer);
                device.setWorkTemperature(workTemperature);
            }
            {
                /* workMomentFlow(工况瞬时流量) */
                String stringBuffer = BytesUtils.subStringByIndex(hexString, calculations(i, DDI.WORK_TEMPERATURE), calculations(i, DDI.WORK_MOMENT_FLOW));
                float workMomentFlow = HexConvertUtils.hexString2Float(stringBuffer);
                device.setWorkMomentFlow(workMomentFlow);
            }
            {
                /* normMomentFlow(标况瞬时流量) */
                String stringBuffer = BytesUtils.subStringByIndex(hexString, calculations(i, DDI.WORK_MOMENT_FLOW), calculations(i, DDI.NORM_MOMENT_FLOW));
                float normMomentFlow = HexConvertUtils.hexString2Float(stringBuffer);
                device.setNormMomentFlow(normMomentFlow);
            }
            {
                /* normMomentFlow(标况瞬时流量) */
                String stringBuffer = BytesUtils.subStringByIndex(hexString, calculations(i, DDI.NORM_MOMENT_FLOW), calculations(i, DDI.BATTERY_LEVEL));
                float batteryLevel = HexConvertUtils.hexString2Float(stringBuffer);
                device.setBatteryLevel(batteryLevel);
            }
            {
                /* end(表数据结尾) */
                String stringBuffer = BytesUtils.subStringByIndex(hexString, calculations(i, DDI.BATTERY_LEVEL), calculations(i, DDI.END));
            }
            devices.add(device);
        }
        return devices;
    }

}
